import { AIConfig, LayaAPICode, LayaAPIStatus } from "./AIConfig";
import { AICore} from "./AICore";
import { AIPanel } from "./AIPanel";
import { AIPluginMgr } from "./AIPluginMgr";
import { AIScriptMgr } from "./AIScriptClassMgr";
import { AITaskGenAudioNode } from "./AITask/AITaskGenAudio";
import { AITaskGenImageNode } from "./AITask/AITaskGenImage";
import { AITaskGenSkyImg } from "./AITask/AITaskGenSkyImg";
import { AITaskTTS } from "./AITask/AITaskTTS";
import { AIUtils, delay } from "./AIUtils";
import { IDEAgent } from "./IDEAgent";
import { getAudio, post } from "./Imagen";
import { LayaAPI } from "./LayaAPI";
import { creatUnlightMtl, createPBRMtl, createSkyPanoramaMtl, getCompByType, getObjectByDataPath, setPropsByRefDataPath } from "./ObjectAndPropDesc";
import { Thinkingdata } from "./Thinkingdata";

var script_Vec3_def = `
//注意：y轴向上，右手坐标系
class Vector3{x;y;z; 
    length():number; 
}
`
class Script_Vector3 {
    //因为需要修改通知，以便处理 position.x+=10这种情况
    wrappedobj:any=null;
    //x=0;y=0;z=0
    constructor(obj:any=null,y?:number,z?:number){
        let wobj=obj;
        if(typeof(obj)=='number'){
            //允许  new Vector3(0,0,0)这种形式
            wobj={x:obj,y,z}
        }else{
            
        }
        this.wrappedobj=wobj
    }
    length(){
        let x = this.wrappedobj.x;
        let y = this.wrappedobj.y;
        let z = this.wrappedobj.z;
        return Math.sqrt(x*x+y*y+z*z)
    }
    set x(v:number){ this.wrappedobj.x=v;}
    set y(v:number){ this.wrappedobj.y=v;}
    set z(v:number){ this.wrappedobj.z=v;}
    get x(){ return this.wrappedobj.x;}
    get y(){ return this.wrappedobj.y;}
    get z(){ return this.wrappedobj.z;}
    set(x:number,y:number,z:number){
        this.x=x;this.y=y;this.z=z;
    }
}

var script_quat_define=`
class Quaternion{x;y;z;w;
    static fromEuler(x,y,z):Quaternion;
    static toEuler():Vector3;
}
`
class Script_Quaternion{
    wrappedobj:any=null;
    constructor(obj:any=null,y?:number,z?:number,w?:number){
        let wobj=obj;
        if(typeof(obj)=='number'){
            //允许  new Quaternion(0,0,0,1)这种形式
            wobj={x:obj,y,z,w}
        }

        this.wrappedobj=wobj;
    }
    set x(v:number){ this.wrappedobj.x=v;}
    set y(v:number){ this.wrappedobj.y=v;}
    set z(v:number){ this.wrappedobj.z=v;}
    set w(v:number){ this.wrappedobj.w=v;}
    get x(){ return this.wrappedobj.x;}
    get y(){ return this.wrappedobj.y;}
    get z(){ return this.wrappedobj.z;}
    get w(){ return this.wrappedobj.w;}

    set(x:number,y:number,z:number,w:number){
        this.x=x;this.y=y;this.z=z;this.w=w;
    }

    //顺序是 y,x,z
    static fromEuler(x: number,y: number, z: number) {
        var halfRoll = z * 0.5;
        var halfPitch = x * 0.5;
        var halfYaw = y * 0.5;

        var sinRoll = Math.sin(halfRoll);
        var cosRoll = Math.cos(halfRoll);
        var sinPitch = Math.sin(halfPitch);
        var cosPitch = Math.cos(halfPitch);
        var sinYaw = Math.sin(halfYaw);
        var cosYaw = Math.cos(halfYaw);

        let ret = new Script_Quaternion(null);
        ret.set(
            (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll),
            (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll),
            (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll),
            (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll)
        );
        return ret;
    }

    toEuler(){
        let q = this.wrappedobj;
        let ysqr = q.y * q.y;

        let t0 = -2.0 * (ysqr + q.z * q.z) + 1.0;
        let t1 = +2.0 * (q.x * q.y - q.w * q.z);
        let t2 = -2.0 * (q.x * q.z + q.w * q.y);
        let t3 = +2.0 * (q.y * q.z - q.w * q.x);
        let t4 = -2.0 * (q.x * q.x + ysqr) + 1.0;

        t2 = t2 > 1.0 ? 1.0 : t2;
        t2 = t2 < -1.0 ? -1.0 : t2;

        let pitch = Math.asin(t2);
        let roll = Math.atan2(t3, t4);
        let yaw = Math.atan2(t1, t0);

        return new Script_Vector3(
            {
                x: pitch * (180/Math.PI),
                y: yaw * (180/Math.PI),
                z: roll * (180/Math.PI),
            }
        );
    }
}

var script_node_define = `
interface INode{
    position:Vector3;
    visible:boolean;
    quaternion:Quaternion;
    name:string;
    scale:Vector3;
    //这个对象的材质。注意返回可能为空
    get_material():Promise<IMaterial|null>;
    set_material(mtl:IMaterial);
}
`

class Script_Node{
    wrappedObj:any=null;
    constructor(obj:any){
        this.wrappedObj=obj;
    }

    get name(){
        return this.wrappedObj.props.name;
    }
    set name(s:string){
        this.wrappedObj.props.name=s;
    }

    set position(p:Script_Vector3){
        if(this.wrappedObj.is3d){
            this.wrappedObj.props.transform.position = p.wrappedobj;
        }else{
            this.wrappedObj.props.x = p.x;
            this.wrappedObj.props.y = p.y;
        }
    }
    //注意这个是引用
    get position(){
        if(this.wrappedObj.is3d){
            return new Script_Vector3(this.wrappedObj.props.transform.position)
        }else{
            let ret = new Script_Vector3(null);
            ret.set(this.wrappedObj.props.x, this.wrappedObj.props.y,0);
            return ret;
        }
    }
    set visible(v:boolean){
        if(this.wrappedObj.is3d){
            this.wrappedObj.props.active = v;
        }else{
            this.wrappedObj.props.visible = v;
        }
    }
    get visible(){
        if(this.wrappedObj.is3d){
            return this.wrappedObj.props.active;
        }else{
            return this.wrappedObj.props.visible;
        }
    }
    set quaternion(v:Script_Quaternion){
        if(this.wrappedObj.is3d){
            this.wrappedObj.props.transform.rotation={x:v.x,y:v.y,z:v.z,w:v.w}
        }
    }
    //注意这个是引用
    get quaternion(){
        if(this.wrappedObj.is3d){
            let q = this.wrappedObj.props.transform.rotation;
            let ret = new Script_Quaternion(q);
            return ret;
        }
    }

    set scale(v:Script_Vector3){
        if(this.wrappedObj.is3d){
            this.wrappedObj.props.transform.localScale = v.wrappedobj;
        }else{
            //TODO
        }
    }

    get scale(){
        if(this.wrappedObj.is3d){
            return new Script_Vector3(this.wrappedObj.props.transform.localScale)
        }
        //TODO
        return null;
    }

    async get_material(): Promise<Script_Material|null> {
        let datapath = (await getCompByType(this.wrappedObj, 'MeshRenderer'))+ '.props.sharedMaterials[0]';
        let mtl = getObjectByDataPath(this.wrappedObj, datapath);
        if(mtl && !mtl._$uuid)
            mtl=null;

        if (mtl && (await IDEAgent.inst.isInnerAsset(mtl._$uuid)))
            //如果是默认材质，也需要重新创建
            mtl = null;

        if (mtl == null) {
            //AI比较单纯，希望每个都有材质
            mtl = await createPBRMtl(`aigc/mtl/mtl_${Date.now()}.lmat`,true);

            await setPropsByRefDataPath(this.wrappedObj,datapath,{_$uuid:mtl.id,_$type: "Material"});  
            await Editor.scene.syncNode(this.wrappedObj)
            mtl = await Editor.scene.getResourceProps(mtl.id);  //转成有属性的

        }
        return new Script_Material(mtl);
    }

    async set_material(mtl:Script_Material){
        let obj = this.wrappedObj;
        let datapath = await getCompByType(obj,'MeshRenderer')+'.props.sharedMaterials[0]';
        // let mtl = getObjectByDataPath(obj, datapath);
        // if(mtl && (await IDEAgent.inst.isInnerAsset(mtl._$uuid)))
        //     //如果是默认材质，也需要重新创建
        //     mtl = null;

        // if(!mtl){

        // }
        await setPropsByRefDataPath(obj,datapath,{_$uuid:mtl.wrappedObj.id,_$type: "Material"});
    }
}

class Script_Box extends Script_Node{}

class Script_Sphere extends Script_Node{}

class Script_Plane extends Script_Node{}

class Script_Panel{
}

class Script_Camera{
    constructor(){
    }
    forward(dist=1){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'foward', dist).then(ret=>{});
    }
    backward(dist=1){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'backward', dist).then(ret=>{});
    }
    moveLeft(dist=1){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'left', dist)
    }
    moveRight(dist=1){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'right', dist)
    }
    moveUp(dist=1){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'up', dist)
    }
    moveDown(dist=1){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'down', dist)
    }
    turnLeft(degree=45){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'rotateleft', degree);
    }
    trunRight(degree=45){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'rotateright', degree);
    }
    turnUp(degree=45){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'rotateup', degree);
    }
    turnDown(degree=45){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'rotatedown', degree);
    }
    focusToObject(node:Script_Node){
        let obj=null;
        if(node && node.wrappedObj){
            obj = node.wrappedObj;
        }else{
            let sel: ReadonlyArray<any> = Editor.scene.getSelection()
            if(sel && sel[0]){
                obj=sel[0]
            }
        }
        if(obj)
            Editor.scene.runScript('AI_CameraCtrl.cmd', 'focus', ''+obj.id).then(ret=>{});
    }
    正交模式(){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'orthographic', true);
    }
    透视模式(){
        Editor.scene.runScript('AI_CameraCtrl.cmd', 'orthographic', false);
    }
}

class Script_Scene{
    skyrender:any;
    constructor(){
    }

    private async getSkyRender(){
        if(this.skyrender)
            return this.skyrender;
        let scene3d = Editor.scene.rootNode.children[0];
        let skyrender = scene3d.props.skyRenderer;
        if(!skyrender){
            await Editor.scene.syncNode(scene3d);   //只有这样才有skyrender
            skyrender = scene3d.props.skyRenderer;
        }
        return skyrender;
    }

    async get_sky_material(){
        let skyrender = this.skyrender;
        if(!skyrender){
            skyrender = await this.getSkyRender();
        }

        return new Script_Material(skyrender.material,true);
    }
    async set_sky_material(mtl:Script_Material){
        AIPanel.ins.addMsg(`非常抱歉，目前设置天空盒功能还不稳定，您可以先生成天空盒图片然后手动设置,具体流程如下：
1. 创建一个SkyPanoramic材质
2. 把生成的贴图设置到材质的panoramic texture上
3. 把这个材质设置到Scene3D对象的 Sky Render的material上。
下面为您打开生成天空盒贴图的功能：
`,-1);
        let t = new AITaskGenSkyImg();
        t.execute();
        return;
        let skyrender = this.skyrender;
        if(!skyrender){
            skyrender = await this.getSkyRender();
        }

        // let curmtl = skyrender.material;
        // if(mtl && ! (await IDEAgent.inst.isInnerAsset(curmtl._$uuid))){
        //     //已经有材质了，且不是默认材质
        //     // 询问是否创建材质
        // }else{
        //     //需要创建新的材质
        // }
        skyrender.material = mtl.wrappedObj;
    }
}

class Script_Asset_Iamge{
    wrappedObj:any=null;
    constructor(obj:any){
        this.wrappedObj=obj;
    }
}

class Script_Material{
    //这个是有 _$uuid的，而不是只有id的。即是实际对象，而不是文件对象
    wrappedObj:any=null;
    assetid:string;
    private isSky=false;
    private datapth='shaderHelper.u_AlbedoTexture'
    constructor(obj:any,issky=false){
        this.wrappedObj=obj;
        this.isSky=issky;
        if(issky){
            this.datapth = 'shaderHelper.u_Texture'
        }
    }

    async get_texture():Promise<Script_Asset_Iamge>{
        let obj = await Editor.scene.getResourceProps(this.wrappedObj._$uuid);

        let tex = getObjectByDataPath(obj,this.datapth);
        return new Script_Asset_Iamge(tex);
    }

    async set_texture(tex:Script_Asset_Iamge){
        let obj = await Editor.scene.getResourceProps(this.wrappedObj._$uuid);
        await setPropsByRefDataPath(obj, this.datapth, { _$uuid: tex.wrappedObj.id });
    }
}

var editorDefine=`
interface IAssetImage{}

interface IMaterial{
    assetid:string;
    //贴图
    async set_texture(img:IAssetImage);
    async get_texture():IAssetImage;
}

var IScene{
    async set_sky_material(mtl:IMaterial);
    async get_sky_material();
}

var IMusic{
    prompt:string;
    duration:number;
}

interface IImageGen{
    //图片描述
    prompt:string
    //负面描述，生成的图片避免有这些内容
    negativePrompt:string
    width:number
    height:number
    //生成几张图片
    count:number
    //图片背景是否透明
    transparent:boolean
    //水平方向是否无缝
    tileX:boolean
    //垂直方向是否无缝
    tileY:boolean
    //保存文件名称
    name:string
    //生成图片的随机种子
    seed:number
    //开始生成
    generate();
    //取消
    cancel();
}

var editor:{
    //创建盒子
    createBox(length=1,width=1,height=1):Promise<ICube>;
    //创建球
    createSphere(radius=1):Promise<INode>;
    //创建面片
    createPlane(length=1,width=1):Promise<INode>;
    //创建空的3d节点
    createSprite3D():Promise<INode>;
    /**
     * 利用AI算法生成图片。
     * @param prompt 图片内容。如果用户没有指出则设置为空
     * @param width 图片的宽度，最大1024
     * @param height 图片的高度，最大1024
     * @param transparent 是否要求图片背景是透明的
     * @returns 
     */
    generateImage(prompt:string, width=512,height=512,transparent=false):Promise<IAssetImage>;
    //得到上一次的图片生成参数
    getLastImageGenerateTask():IImageGen;
    //生成音乐。prompt是对音乐的描述，如果没有描述就用空,duration是时长，单位是秒，默认10秒，不要超过1分钟。refMusic是参考音乐，如果没有指定就为空
    generateAudio(prompt:string, duration=10, outName:string, refMusic=null);
    //得到上一次生成的音乐参数
    getLastAudioGenerateTask():IMusic;
    
    //得到上一次提到声音文件（参考音乐）。当生成音乐的时候，如果希望修改或者参考'上面的'文件，就通过这个获得
    getLastAudioFile():string;
    //生成一个全景图(天空盒)图片，用来给天空球材质
    generatePanoramaImage(prompt:string,indoor=false)
    //根据文本生成一个语音文件。username是要模仿的角色名
    textToSpeech(text='', username=''):IAsset;
    //打开界面
    openPanel(panelName:string):IPanel
    //关闭界面
    hidePanel(panelName:string);
    openTool(toolName:string):void
    getCamera():ICamera;
    getScene():IScene;
    //获取选中对象。由于可以多选，所以返回的是数组。
    getSelected():INode[];
    //查找场景中名字为name的INode对象
    findByName(name:string):Promise<INode|null>;
    /**
     * 创建材质。mtlType是材质类型
     * @param mtlType :材质类型，一共三种。PBR 默认值。 Unlit 不需要光照的材质。 SkyPanoramic 天空球材质
     * @param name: 材质的名称
     */
    createMaterial(mtlType:"PBR"|"UnLit"|"SkyPanoramic", name):Promise<IMaterial>;

    //烘焙场景光照
    bakeIBL();
    //开始试玩
    play():void;

    //清空聊天窗口
    clearChatPanel();
    //你想对用户说的话
    speakToUser(your_response);

    //要对AI说的话
    speakToAI(str):Promise<string>
}


`

class MusicEditor{
    wrappedobj:AITaskGenAudioNode;
    constructor(obj:AITaskGenAudioNode){
        this.wrappedobj=obj;
    }

    set prompt(p:string){
        this.wrappedobj.data.desc=p;
        this.wrappedobj.renderUI();
    }

    get prompt(){
        return this.wrappedobj.data.desc;
    }

    set duration(n:number){
        this.wrappedobj.data.duration=n;
        this.wrappedobj.renderUI();
    }

    get duration(){
        return this.wrappedobj.data.duration;
    }
}

class ImageEditor{
    wrappedobj:AITaskGenImageNode;
    constructor(obj:AITaskGenImageNode){
        this.wrappedobj=obj;
    }

    set prompt(v:string){
        this.wrappedobj.data.desc=v;
        this.wrappedobj.renderUI();
    }
    get prompt(){
        return this.wrappedobj.data.desc;
    }

    get negativePrompt(){
        return this.wrappedobj.data.negPrompt;
    }
    set negativePrompt(v:string){
        this.wrappedobj.data.negPrompt=v;
        this.wrappedobj.renderUI();
    }

    get width(){
        return this.wrappedobj.data.width;
    }
    set width(v:number){
        this.wrappedobj.data.width=v;
        this.wrappedobj.renderUI();
    }

    get height(){
        return this.wrappedobj.data.height;
    }

    set height(v:number){
        this.wrappedobj.data.height=v;
        this.wrappedobj.renderUI();
    }

    get count(){
        return this.wrappedobj.data.number;
    }
    set count(v:number){
        this.wrappedobj.data.number=v;
        this.wrappedobj.renderUI();
    }

    get transparent(){
        return this.wrappedobj.data.transparent;
    }
    set transparent(v:boolean){
        this.wrappedobj.data.transparent=v;
        this.wrappedobj.renderUI();
    }

    get tileX(){
        return this.wrappedobj.data.tilex;
    }
    set tileX(v:boolean){
        this.wrappedobj.data.tilex=v;
        this.wrappedobj.renderUI();
    }
    get tileY(){
        return this.wrappedobj.data.tiley;
    }
    set tileY(v:boolean){
        this.wrappedobj.data.tiley=v;
        this.wrappedobj.renderUI();
    }
    get name(){
        return this.wrappedobj.data.assetName
    }
    set name(v:string){
        this.wrappedobj.data.assetName=v;
        this.wrappedobj.renderUI();
    }
    get seed(){
        return this.wrappedobj.data.seed
    }
    set seed(v:number){
        this.wrappedobj.data.seed=v;
        this.wrappedobj.renderUI();

    }

    generate(){
        this.wrappedobj.genImage();
    }
    cancel(){
        this.wrappedobj.cancel();
    }
}

class Script_Editor{
    private async createNode(type: string) {
        const scene = Editor.scene;
        let newNode = await scene.createNode(type, {name: type})
        if (newNode) {
            scene.addNode(null, newNode);
            scene.setSelection(newNode);
        }
        return newNode;
    }

    private is3DScene(){
        if(Editor.scene.worldType=='2d'||Editor.scene.worldType=='gui'){
            AI.getAIPanel().addMsg('无法完成:请打开3d场景再执行此操作。',-1);
            return false;
        }
        return true;
    }

    async createBox(length=1,width=1,height=1){
        if(!this.is3DScene()) return null;
        let cube = await this.createNode("Cube");
        if(cube){
            if(!cube.props.transform)
                cube.props.transform={}
            cube.props.transform.localScale={x:length,y:height,z:width};
        }
        return new Script_Node(cube);
    }

    //创建球
    async createSphere(radius=1){
        if(!this.is3DScene()) return null;
        let sphere = await this.createNode("Sphere");
        if(sphere){
            if(!sphere.props.transform)
                sphere.props.transform={}
            sphere.props.transform.localScale={x:radius,y:radius,z:radius};
        }
        return new Script_Node(sphere);
    }

    //创建面片
    async createPlane(length=1,width=1){
        if(!this.is3DScene()) return null;
        let plane = await this.createNode("Plane");
        if(plane){
            if(!plane.props.transform)
                plane.props.transform={}
            plane.props.transform.localScale={x:length,y:1,z:width};
        }
        return new Script_Node(plane);
    }
    //创建空的3d节点
    async createSprite3D(){
        let root: any = Editor.scene.rootNode.children[0];
        let newNode = await Editor.scene.createNode("Sprite3D", {name: "Sprite3D"}, root);
        if (newNode) {
            Editor.scene.addNode(root, newNode, -1).then(()=>{
                Editor.scene.setSelection(newNode);
            });
            return new Script_Node(newNode)
        }
        return null;
    }

    private _lastGenImage:AITaskGenImageNode=null;
    /**
     * 生成图片。
     * @param prompt 对图片内容的描述
     * @param width 图片的宽度，最大1024
     * @param height 图片的高度，最大1024
     * @param transparent 是否要求图片背景是透明的
     * @returns 
     */
    async generateImage(prompt='', width=512,height=512, transparent=false){
        let task = new AITaskGenImageNode();
        this._lastGenImage=task;
        task.data.width=width;
        task.data.height=height;
        task.data.transparent = transparent;
        task.data.seed = Math.floor(Math.random()*100000);
        if(!prompt){
            await task.execute();
            return new Script_Asset_Iamge( task.genAsset)
        }else{
            //task.showUI=false;
            task.data.desc = prompt;
            return new  Script_Asset_Iamge(await task.genImage(true));
        }
    }

    getLastImageGenerateTask(){
        if(AICore.inst.memory.getCurEditObjName()==AITaskGenImageNode.EditObjName){
            return new ImageEditor(this._lastGenImage);
        }
        return null;
    }    

    private _lastAudio:AITaskGenAudioNode=null;
    async generateAudio(prompt='', duration=10, name='aigen.mp3', refMusic:string=null){
        if(!prompt){
            let task = new AITaskGenAudioNode();
            this._lastAudio=task;
            task.data.duration=duration;
            task.data.refMusic = refMusic;
            await task.execute();
            return task.genAsset;
        }
        let task = new AITaskGenAudioNode();
        return await task.generateMusic(true);
    }

    getLastAudioGenerateTask(){
        if(AICore.inst.memory.getCurEditObjName()==AITaskGenAudioNode.EditObjName){
            return new MusicEditor(this._lastAudio);
        }
    }

    getLastAudioFile(){
        let ai = AICore.inst;
        return ai.memory.getLastAudioFile();
    }
    

    async generatePanoramaImage(prompt='',indoor=false){
        let gensky = new AITaskGenSkyImg()

        gensky._data.template=indoor?"0":"1";
        if(!prompt){
            //创建界面
            await gensky.execute();
        }else{
            gensky._data.prompt=prompt;
            await gensky.genImage();
        }

        return new Script_Asset_Iamge(gensky.genAsset);
    }

    async textToSpeech(text:string, username:string){
        let t = new AITaskTTS();
        t.data.text=text??"你好";
        t.data.charactor=username;
        let asset = await t.execute();
        return asset;
    }

    /**
     *
     * @param mtlType :PBR 默认值。 Unlit 不需要光照的材质。 SkyPanoramic 天空球材质
     */
    async createMaterial(mtlType:"PBR"|"Unlit"|"SkyPanoramic"='PBR', name='aigen.lmat'){
        if(!name)name='aigen.lmat';
        if(!name.endsWith('.lmat')){
            name+='.lmat';
        }
        name=`aigc/mtl/${name}`;
        let outasset=null;
        let issky=false;
        switch(mtlType){
            case 'PBR':
                outasset = await createPBRMtl(name,true);
                break;
            case 'Unlit':
                outasset = await creatUnlightMtl(name,true);
                break;
            case 'SkyPanoramic':
                outasset = await createSkyPanoramaMtl(name,true);
                issky=true;
                break;
        }
        outasset= await Editor.scene.getResourceProps(outasset.id);
        return new Script_Material(outasset,issky);
    }

    //打开界面
    openPanel(panelName:string):Script_Panel{
        let aipanel = AIPanel.ins;
        switch(panelName){
            case '项目设置面板'://项目设置
                Editor.panelManager.showPanel('ProjectSettingsPanel');
                break;
            case '项目发布面板'://发布面板
                Editor.panelManager.showPanel('BuildSettingsPanel');
                break;
            case '动画编辑面板'://动画面板
                Editor.panelManager.showPanel('TimelinePanel');
                break;
            case '小部件面板'://小部件
                Editor.panelManager.showPanel('WidgetsPanel');
                break;
            case '层级面板'://层级面板
                Editor.panelManager.showPanel('HierarchyPanel');
                break;
            case '控制台面板'://console
                Editor.panelManager.showPanel('ConsolePanel');
                break;
            case '属性面板':
                Editor.panelManager.showPanel('InspectorPanel');
                break;
            case '动画状态机面板'://state m
                Editor.panelManager.showPanel('AnimatorControllerPanel');
                break;
            case '显示设置面板': //display
                Editor.panelManager.postMessage("ScenePanel", "showSceneViewSettingsDialog", "canvas");
                break;
            default:
                aipanel.addMsg('不认识的界面:'+panelName,-1);

        }
        return null;
    }

    hidePanel(panelName:string):Script_Panel{
        let aipanel = AIPanel.ins;
        switch(panelName){
            case '项目设置面板'://项目设置
                Editor.panelManager.hidePanel('ProjectSettingsPanel');
                break;
            case '项目发布面板'://发布面板
                Editor.panelManager.hidePanel('BuildSettingsPanel');
                break;
            case '动画编辑面板'://动画面板
                Editor.panelManager.hidePanel('TimelinePanel');
                break;
            case '小部件面板'://小部件
                Editor.panelManager.hidePanel('WidgetsPanel');
                break;
            case '层级面板'://层级面板
                Editor.panelManager.hidePanel('HierarchyPanel');
                break;
            case '控制台面板'://console
                Editor.panelManager.hidePanel('ConsolePanel');
                break;
            case '属性面板':
                Editor.panelManager.hidePanel('InspectorPanel');
                break;
            case '动画状态机面板'://state m
                Editor.panelManager.hidePanel('AnimatorControllerPanel');
                break;
            // case '显示设置面板': //display
            //     Editor.panelManager.postMessage("ScenePanel", "showSceneViewSettingsDialog", "canvas");
            //     break;
            default:
                aipanel.addMsg('不认识的界面:'+panelName,-1);

        }
        return null;
    }    

    openTool(toolname:string){
        let aipanel = AIPanel.ins;
        switch(toolname){
            case '图集打包工具':
                (Editor as any).hotkeyManager.emit("TexturePacker");
                break;
            case '按钮皮肤工具':
                (Editor as any).hotkeyManager.emit("MakeButtonSkin");
                break;
            case '动画烘焙工具':
                (Editor as any).hotkeyManager.emit("BakeAnimation");
                break;
            case '骨骼转换工具':
                (Editor as any).hotkeyManager.emit("SkeletonConverter");
                break;
            default:
                aipanel.addMsg('不认识的工具:'+toolname,-1);
        }
    }

    getCamera(){
        return new Script_Camera()
    }

    getScene(){
        return new Script_Scene();
    }


    //获取选中对象
    getSelected():Script_Node[]{
        let selects = Editor.scene.getSelection();
        let ret:Script_Node[] = [];
        selects.forEach((v)=> {
            ret.push(new Script_Node(v))
        });
        return ret;
    }

    async getCompByType(data:any,type:string, onlyPath=true, recursive=false, syncNode=false){
        await Editor.scene.syncNode(data);
        if(!data.components)
            return null;
        for(let m in data.components){
            let comp = data.components[m];
            if(comp.type==type || comp._$type==type){
                if(onlyPath)
                    return 'components.'+m;
                else
                    return comp;
            }
        }

        if(recursive){
            let retpath = '';
            if(!data.children){
                return null;
            }
            if(onlyPath){
                retpath = 'children';
            }
            await Editor.scene.getNodeChildren(data);
            for(let i=0,n=data.children.length; i<n; i++){
                let child = data.children[i];
                // let comp = await getCompByType(child,type,onlyPath,recursive) as any;
                // if(comp)
                //     return comp;
            }
        }
        return null;
    }


    async findByName(name:string):Promise<Script_Node>{
        let r = await Editor.scene.findNodes(name);
        for( let i=0; i<r.length; i++){
            if(r[i].props.name==name){
                Editor.scene.setSelection(r[i])
                return new Script_Node(r[i]);
            }
        }
        return null;
    }

    bakeIBL(){
        Editor.panelManager.postMessage("ScenePanel", "startBake", false);
    }

    //开始试玩
    play(){
        (Editor as any).hotkeyManager.emit("play");
    }

    clearChatPanel(){
        AIPanel.ins.clear();
    }

    speakToUser(your_response:string){
        AIPanel.ins.addMsg(your_response,-1);
    }

    async speakToAI(str:string){
        let wmsg = await AIPanel.ins.startWaitMsg('...')
        let res:any = await LayaAPI.create().laya_chatgpt(str);
        AIPanel.ins.removeMsg(wmsg);
        //str = await chatgpt_chat(prompt, msg, null, false)
        if (!res || res.code !== LayaAPICode.CodeSuccess || res.data.status !== LayaAPIStatus.TaskStatusDone) {
            return;
        }
        str = res.data.content as string;
        AIPanel.ins.addMsg(str,-1);
    }

    explain(str:string){
        AIPanel.ins.addMsg(str,-1);
    }

    help(){
        Thinkingdata.ins.track("help",{});
    }
}

export class AIInterface_Editor{
    onSelectionChanged(){

    }

    onAdded(mgr:AIPluginMgr){
        mgr.setAIInterface('math_vec3', script_Vec3_def, {"Vector3":Script_Vector3});
        mgr.setAIInterface('math_quat', script_quat_define,{'Quaternion':Script_Quaternion});
        mgr.setAIInterface('inode', script_node_define);
        mgr.setAIInterface('editorcam',`
interface ICamera extends INode{
    forward(dist=1);
    backward(dist=1);
    moveLeft(dist=1);
    moveRight(dist=1);
    moveUp(dist=1);
    moveDown(dist=1);
    turnLeft(degree=45);
    trunRight(degree=45);
    turnUp(degree=45);
    turnDown(degree=45);
    focusToObject(node:INode)
    正交模式();
    透视模式();
}  
interface ICube extends INode{
}

//所有的界面列表
[
    '属性面板',
    '项目设置面板',
    '项目发布面板',
    //动画编辑面板又叫做时间线面板
    '动画编辑面板',
    '小部件面板',
    //层级面板显示对象列表和父子关系
    '层级面板',
    '控制台面板',
    '动画状态机面板',
    '显示设置面板'
]

//所有的工具列表
[
    //把独立的散图打包成一张大图，提高运行效率
    '图集打包工具',
    // 制作按钮的外观
    '按钮皮肤工具',
    // 预计算动画矩阵，提高运行效率
    '动画烘焙工具',
    // 骨骼转换工具用来把spine或者龙骨的动画格式转成laya的格式
    '骨骼转换工具'
]
//界面接口
interface IPanel{
}        
        `);

        mgr.setAIInterface('editorcore', editorDefine, {'editor':new Script_Editor()})
    }
}

AIScriptMgr.regClass('Script_Vector3',Script_Vector3);
AIScriptMgr.regClass('Script_Quaternion',Script_Quaternion);
AIScriptMgr.regClass('Script_Node',Script_Node);